<template>
  <div class="app-container">
    <!-- 左侧用户列表 -->
    <div class="user-list">
      <div 
        v-for="user in userList" 
        :key="user.userId"
        :class="['user-item', selectedUserId === user.userId ? 'active' : '']"
        @click="selectUser(user)"
      >
        <div class="user-info">
          <div class="user-name">{{ user.userName }}</div>
          <div class="last-message">{{ user.lastMessage }}</div>
        </div>
        <div class="message-time">{{ formatTime(user.lastTime) }}</div>
        <!-- 添加未读消息提示 -->
        <div v-if="user.unreadCount" class="unread-count">
          {{ user.unreadCount }}
        </div>
      </div>
    </div>

    <!-- 右侧聊天区域 -->
    <div class="chat-area">
      <!-- 搜索栏优化 -->
      <div class="filter-container">
        <el-input
          v-model="listQuery.keyword"
          placeholder="请输入标题关键词"
          style="width: 200px;"
          class="filter-item"
          clearable
          @keyup.enter.native="handleFilter"
        >
          <i slot="prefix" class="el-input__icon el-icon-search"></i>
        </el-input>
        <el-button class="filter-item" type="primary" @click="handleFilter">
          搜索
        </el-button>
        <el-button class="filter-item" type="success" @click="handleCreate">
          <i class="el-icon-plus"></i>
          新增笔记
        </el-button>
        <el-button class="filter-item" type="info" @click="showAnalysis">
          <i class="el-icon-data-analysis"></i>
          数据分析
        </el-button>
      </div>

      <!-- 列表优化 -->
      <el-table
        v-loading="listLoading"
        :data="list"
        style="width: 100%"
        border
        fit
        highlight-current-row
      >
        <el-table-column
          prop="id"
          label="ID"
          width="80"
        />
        <el-table-column
          prop="title"
          label="标题"
        />
        <el-table-column
          prop="coverImage"
          label="封面图"
          width="180"
        >
          <template v-slot="scope">
            <el-image
              :src="getServerUrl() + scope.row.images"
              style="width: 100px; height: 60px"
              fit="cover"
            >
              <div slot="error" class="image-slot">
                <i class="el-icon-picture-outline"></i>
              </div>
            </el-image>
          </template>
        </el-table-column>
        <el-table-column
          prop="createTime"
          label="发布时间"
          width="180"
        >
          <template v-slot="scope">
            <span>{{ formatDateTime(scope.row.createTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="views"
          label="浏览量"
          width="100"
        />
        <el-table-column
          label="操作"
          width="200"
          align="center"
          fixed="right"
        >
          <template v-slot="scope">
            <el-button
              size="mini"
              type="primary"
              @click="handleEdit(scope.row)"
            >
              编辑
            </el-button>
            <el-button
              size="mini"
              type="danger"
              @click="handleDelete(scope.row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <pagination
        v-show="total>0"
        :total="total"
        v-model:page="listQuery.pageNum"
        v-model:limit="listQuery.pageSize"
        @pagination="getList"
      />

      <!-- 弹窗优化 -->
      <el-dialog
        v-model="dialogFormVisible"
        :title="dialogStatus === '添加' ? '新增笔记' : '编辑笔记'"
        :close-on-click-modal="false"
        :destroy-on-close="true"
        width="650px"
        center
      >
        <el-form
          ref="dataFormRef"
          :rules="rules"
          :model="temp"
          label-position="right"
          label-width="100px"
          style="padding: 0 20px"
        >
          <el-form-item label="标题" prop="title">
            <el-input v-model="temp.title" placeholder="请输入标题"/>
          </el-form-item>
          <el-form-item label="封面图" prop="coverImage">
            <el-upload
              ref="uploadRef"
              class="avatar-uploader"
              :action="uploadUrl"
              :headers="headers"
              :show-file-list="false"
              :on-success="handleImageSuccess"
              :before-upload="beforeImageUpload"
            >
              <img v-if="imageUrl" :src="imageUrl" class="avatar" />
              <div v-else class="avatar-uploader-icon">
                <i class="el-icon-plus"></i>
              </div>
            </el-upload>
            <div class="el-upload__tip">
              <i class="el-icon-info"></i>
              只能上传jpg格式图片，且不超过2MB
            </div>
          </el-form-item>
          <el-form-item label="正文内容" prop="content">
            <el-input
              v-model="temp.content"
              type="textarea"
              :rows="6"
              placeholder="请输入正文内容"
            />
          </el-form-item>
        </el-form>
        <div class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取 消</el-button>
          <el-button type="primary" @click="dialogStatus==='添加'?createData():updateData()">
            确 定
          </el-button>
        </div>
      </el-dialog>

      <!-- 添加数据分析对话框 -->
      <el-dialog
        title="笔记数据分析"
        v-model="analysisDialogVisible"
        width="80%"
        :destroy-on-close="true"
      >
        <div class="analysis-container">
          <el-row :gutter="20">
            <!-- 数据概览卡片 -->
            <el-col :span="8">
              <el-card class="data-card">
                <div class="card-header">
                  <span>总笔记数</span>
                </div>
                <div class="card-content">
                  <span class="number">{{ analysisData.totalNotes }}</span>
                </div>
              </el-card>
            </el-col>
            <el-col :span="8">
              <el-card class="data-card">
                <div class="card-header">
                  <span>本月新增</span>
                </div>
                <div class="card-content">
                  <span class="number">{{ analysisData.monthlyNotes }}</span>
                </div>
              </el-card>
            </el-col>
            <el-col :span="8">
              <el-card class="data-card">
                <div class="card-header">
                  <span>总浏览量</span>
                </div>
                <div class="card-content">
                  <span class="number">{{ analysisData.totalViews }}</span>
                </div>
              </el-card>
            </el-col>
          </el-row>

          <!-- 图表区域 -->
          <el-row :gutter="20" class="chart-row">
            <el-col :span="12">
              <el-card class="chart-card">
                <div class="card-header">
                  <span>笔记发布趋势</span>
                </div>
                <div class="chart" ref="trendChart"></div>
              </el-card>
            </el-col>
            <el-col :span="12">
              <el-card class="chart-card">
                <div class="card-header">
                  <span>浏览量排行</span>
                </div>
                <div class="chart" ref="rankChart"></div>
              </el-card>
            </el-col>
          </el-row>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import  axios from '@/util/axios'
import {getServerUrl} from "@/config/sys";
import Pagination from '@/components/Pagination'
import { ref, onMounted, onUnmounted } from 'vue'
import { formatDate, getRelativeTime } from '@/utils/date'
import * as echarts from 'echarts'
import { LineChart, BarChart } from 'echarts/charts'
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent
} from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'

// 注册必需的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  LineChart,
  BarChart,
  CanvasRenderer
])

const messages = ref([])
const userList = ref([])
const selectedUserId = ref('')
const selectedUser = ref(null)
const inputMessage = ref('')
const hasMore = ref(true)
const pageSize = ref(20)
const ws = ref(null)

// 加载离线消息
const loadOfflineMessages = async () => {
  try {
    const { data } = await axios.get('chatMessage/offline')
    if (data.code === 200) {
      // 处理离线消息
      data.data.forEach(message => {
        handleNewMessage(message)
      })
    }
  } catch (error) {
    console.error('加载离线消息失败:', error)
  }
}

// 加载历史消息
const loadHistoryMessages = async () => {
  if (!selectedUserId.value || !hasMore.value) return
  
  try {
    const { data } = await axios.get('chatMessage/history', {
      params: {
        userId: 'admin',
        customerId: selectedUserId.value,
        limit: pageSize.value
      }
    })
    
    if (data.code === 200) {
      const newMessages = data.data.messages
      messages.value = [...newMessages, ...messages.value]
      hasMore.value = newMessages.length === pageSize.value
    }
  } catch (error) {
    console.error('加载历史消息失败:', error)
  }
}

// 保存消息到数据库
const saveMessage = async (message) => {
  try {
    await axios.post('chatMessage/save', message)
  } catch (error) {
    console.error('保存消息失败:', error)
  }
}

// 发送消息
const handleSend = async () => {
  if (!inputMessage.value.trim() || !selectedUserId.value) return
  
  const message = {
    fromUserId: 'admin',
    toUserId: selectedUserId.value,
    content: inputMessage.value,
    sendTime: new Date().toISOString(),
    messageType: 1,
    status: 0 // 0: 未读, 1: 已读
  }
  
  // 保存消息到数据库
  await saveMessage(message)
  
  // 发送消息
  ws.value?.send(JSON.stringify(message))
  messages.value.push(message)
  inputMessage.value = ''
  scrollToBottom()
}

// 处理新消息
const handleNewMessage = (message) => {
  // 更新消息列表
  if(message.fromUserId === selectedUserId.value) {
    messages.value.push(message)
    scrollToBottom()
    // 标记消息为已读
    markMessageAsRead(message.id)
  }
  
  // 更新用户列表
  const userIndex = userList.value.findIndex(user => user.userId === message.fromUserId)
  if(userIndex > -1) {
    const user = userList.value[userIndex]
    user.lastMessage = message.content
    user.lastTime = message.sendTime
    if(message.fromUserId !== selectedUserId.value) {
      user.unreadCount = (user.unreadCount || 0) + 1
    }
  } else {
    userList.value.unshift({
      userId: message.fromUserId,
      userName: `用户${message.fromUserId}`,
      lastMessage: message.content,
      lastTime: message.sendTime,
      unreadCount: 1
    })
  }
}

// 标记消息为已读
const markMessageAsRead = async (messageId) => {
  try {
    await axios.post(`chatMessage/read/${messageId}`)
  } catch (error) {
    console.error('标记消息已读失败:', error)
  }
}

// 选择用户
const selectUser = async (user) => {
  selectedUserId.value = user.userId
  selectedUser.value = user
  messages.value = []
  hasMore.value = true
  // 清除未读计数
  user.unreadCount = 0
  await loadHistoryMessages()
}

onMounted(async () => {
  // 先加载离线消息
  await loadOfflineMessages()
  // 然后初始化WebSocket连接
  initWebSocket()
})

export default {
  name: 'Note',
  components: { Pagination },
  data() {
    return {
      list: [],
      total: 0,
      listQuery: {
        pageNum: 1,
        pageSize: 10,
        keyword: ''
      },
      temp: {
        id: undefined,
        title: '',
        content: '',
        coverImage: ''
      },
      dialogFormVisible: false,
      dialogStatus: '',
      rules: {
        title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
        content: [{ required: true, message: '内容不能为空', trigger: 'blur' }]
      },
      imageUrl: '',
      headers: {
        'token': window.sessionStorage.getItem('token')
      },
      uploadUrl: getServerUrl() + '/admin/note/uploadImage',
      listLoading: false,
      analysisDialogVisible: false,
      analysisData: {
        totalNotes: 0,
        monthlyNotes: 0,
        totalViews: 0,
        trendData: [],
        rankData: []
      },
      charts: {
        trendChart: null,
        rankChart: null
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    getServerUrl,
    getList() {
      this.listLoading = true

    const url = 'note/list';
    const params = this.listQuery;
    // 手动拼接参数到URL上
    let queryString = '';
    for (const key in params) {
      if (params.hasOwnProperty(key)) {
        if (queryString.length > 0) {
          queryString += '&';
        }
        queryString += `${key}=${params[key]}`;
      }
    }
    const fullUrl = `${url}?${queryString}`;
    console.log("fullUrl:", fullUrl)
      axios.get(fullUrl).then(response => {
        console.log("response",response)
        this.list = response.data.data.records
        this.total = response.data.data.total
      }).finally(() => {
        this.listLoading = false
      })
    },
    handleFilter() {
      this.listQuery.pageNum = 1
      this.getList()
    },
    resetTemp() {
      this.temp = {
        id: undefined,
        title: '',
        content: '',
        coverImage: ''
      }
      this.imageUrl = ''
      if (this.$refs.uploadRef) {
        this.$refs.uploadRef.clearFiles()
      }
    },
    handleCreate() {
      this.resetTemp()
      this.dialogStatus = '添加'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        if (this.$refs.dataFormRef) {
          this.$refs.dataFormRef.clearValidate()
        }
      })
    },
    createData() {
      this.$refs.dataFormRef.validate(async (valid) => {
        if (valid) {
          try {
            if (!this.temp.images) {
              this.$message.warning('请上传封面图')
              return
            }
            
            const response = await axios.post('note/add', {
              ...this.temp,
              images: this.temp.images
            })
            
            if (response.data.code === 0) {
              this.dialogFormVisible = false
              this.$notify({
                title: '成功',
                message: '创建成功',
                type: 'success',
                duration: 2000
              })
              this.getList()
            } else {
              this.$message.error(response.data.msg || '创建失败')
            }
          } catch (error) {
            this.$message.error('创建失败：' + error.message)
          }
        }
      })
    },
    handleEdit(row) {
      this.temp = Object.assign({}, row)
      this.imageUrl = row.images
      this.dialogStatus = '编辑'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        if (this.$refs.dataFormRef) {
          this.$refs.dataFormRef.clearValidate()
        }
      })
    },
    updateData() {
      this.$refs.dataFormRef.validate((valid) => {
        if (valid) {
          if (!this.temp.images) {
            this.$message.warning('请上传封面图')
            return
          }
          
          axios.post('note/update', {
            ...this.temp,
            images: this.temp.images
          }).then(response => {
            if (response.data.code === 0) {
              this.dialogFormVisible = false
              this.$notify({
                title: '成功',
                message: '更新成功',
                type: 'success',
                duration: 2000
              })
              this.getList()
            } else {
              this.$message.error(response.data.msg || '更新失败')
            }
          }).catch(error => {
            this.$message.error('更新失败：' + error.message)
          })
        }
      })
    },
    handleDelete(row) {
      this.$confirm('确认删除?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        axios.post(`note/delete/${row.id}`).then(() => {
          this.$notify({
            title: '成功',
            message: '删除成功',
            type: 'success',
            duration: 2000
          })
          this.getList()
        })
      })
    },
    beforeImageUpload(file) {
      const isJPG = file.type === 'image/jpeg'
      const isLt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        this.$message.error('图片必须是jpg格式')
        return false
      }
      if (!isLt2M) {
        this.$message.error('图片大小不能超过2MB!')
        return false
      }
      return isJPG && isLt2M
    },
    handleImageSuccess(res) {
      if (res.code === 0) {
        this.imageUrl = getServerUrl() + res.data.src
        this.temp.images = res.data.src
        this.$message.success('图片上传成功')
      } else {
        this.$message.error(res.msg || '上传失败')
      }
    },
    handleDialogClose() {
      this.resetTemp()
      this.$refs.dataFormRef?.clearValidate()
    },
    formatDateTime(time) {
      if (!time) return '-'
      const date = new Date(time)
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      const hours = String(date.getHours()).padStart(2, '0')
      const minutes = String(date.getMinutes()).padStart(2, '0')
      return `${year}-${month}-${day} ${hours}:${minutes}`
    },
    formatTime(time) {
      return getRelativeTime(time)
    },
    scrollToBottom() {
      // 实现滚动到底部的逻辑
    },
    initWebSocket() {
      // 初始化WebSocket连接的逻辑
    },
    async showAnalysis() {
      this.analysisDialogVisible = true
      await this.loadAnalysisData()
      this.$nextTick(() => {
        this.initCharts()
      })
    },
    async loadAnalysisData() {
      try {
        const response = await axios.get('note/analysis')
        if (response.data.code === 0) {
          this.analysisData = response.data.data
        }
      } catch (error) {
        this.$message.error('加载分析数据失败：' + error.message)
      }
    },
    initCharts() {
      // 初始化发布趋势图
      this.charts.trendChart = echarts.init(this.$refs.trendChart)
      this.charts.trendChart.setOption({
        title: { text: '近30天笔记发布趋势' },
        tooltip: { trigger: 'axis' },
        xAxis: {
          type: 'category',
          data: this.analysisData.trendData.map(item => item.date)
        },
        yAxis: { type: 'value' },
        series: [{
          data: this.analysisData.trendData.map(item => item.count),
          type: 'line',
          smooth: true
        }]
      })
      
      // 初始化浏览量排行图
      this.charts.rankChart = echarts.init(this.$refs.rankChart)
      this.charts.rankChart.setOption({
        title: { text: '笔记浏览量TOP10' },
        tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
        xAxis: { type: 'value' },
        yAxis: {
          type: 'category',
          data: this.analysisData.rankData.map(item => item.title)
        },
        series: [{
          type: 'bar',
          data: this.analysisData.rankData.map(item => item.views)
        }]
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.filter-container {
  padding-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.filter-item {
  margin-right: 10px;
}

/* 封面图上传样式优化 */
.avatar-uploader {
  text-align: center;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
}

.avatar {
  width: 178px;
  height: 178px;
  display: block;
  object-fit: cover;
}

.el-upload__tip {
  color: #909399;
  font-size: 12px;
  margin-top: 8px;
  line-height: 1.4;
  display: flex;
  align-items: center;
}

.el-upload__tip i {
  margin-right: 4px;
  color: #E6A23C;
}

/* 表格样式优化 */
.el-table {
  margin-top: 15px;
}

.image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: #f5f7fa;
  color: #909399;
  font-size: 30px;
}

/* 移除不需要的自定义弹窗样式 */
.custom-dialog,
.dialog-wrapper,
.dialog-header,
.dialog-body,
.close-btn {
  display: none;
}

.el-dialog__body {
  padding: 20px 0;
}

.dialog-footer {
  text-align: right;
  padding-top: 20px;
}

.unread-count {
  position: absolute;
  top: 10px;
  right: 10px;
  background: #f56c6c;
  color: white;
  border-radius: 10px;
  padding: 0 6px;
  min-width: 20px;
  height: 20px;
  line-height: 20px;
  text-align: center;
  font-size: 12px;
}

.user-item {
  position: relative;
  /* ... 其他样式保持不变 ... */
}

.analysis-container {
  padding: 20px;
  
  .data-card {
    margin-bottom: 20px;
    
    .card-header {
      font-size: 16px;
      color: #606266;
      margin-bottom: 10px;
    }
    
    .card-content {
      .number {
        font-size: 24px;
        font-weight: bold;
        color: #409EFF;
      }
    }
  }
  
  .chart-row {
    margin-top: 20px;
    
    .chart-card {
      .card-header {
        font-size: 16px;
        color: #606266;
        margin-bottom: 15px;
      }
      
      .chart {
        height: 300px;
      }
    }
  }
}
</style>
